<template>
    <el-dialog
        class="hand-strategy-dialog"
        :visible.sync="isOpenDialog"
        center
        :close-on-click-modal="false"
        :width="'98%'"
    >
        <div slot="title">
            <div v-html="getFlopBoardHtml(board)"></div>
        </div>
        <div class="hand-strategy">
            <div class="hand-table">
                <div
                    class="hand-table-row"
                    v-for="index of cardRange"
                    :key="index"
                >
                    <div
                        class="hand-table-cell"
                        v-for="index2 of cardRange"
                        :key="index2"
                        @mouseenter="handleCardChange(index, index2)"
                    >
                        <bet-render
                            :betPercents="
                                cellStrategy[getCellDesc(index, index2)]
                            "
                            :height="getRangeHeight(index, index2)"
                        ></bet-render>
                        <div class="hand-desc">
                            {{ getCellDesc(index, index2) }}
                        </div>
                    </div>
                </div>
            </div>
            <div class="strategy-middle" v-if="currentSelectHand">
                <bet-summary :betSummary="betSummary"></bet-summary>
                <div class="bet-detail" :class="handClass">
                    <div
                        class="bet-detail-item"
                        v-for="item of currentHands"
                        :key="item"
                    >
                        <div
                            class="detail-item-title"
                            v-html="getHandHtml(item)"
                        ></div>
                        <div
                            class="detail-item-content"
                            v-if="
                                handStrategy[item] &&
                                checkHandFilterFlag(handStrategy[item])
                            "
                        >
                            <bet-render
                                :betPercents="handStrategy[item].bet"
                                :height="`${handStrategy[item].combos * 100}%`"
                            ></bet-render>
                        </div>
                        <div
                            class="detail-item-graph"
                            v-if="
                                handStrategy[item] &&
                                checkHandFilterFlag(handStrategy[item])
                            "
                        >
                            <div
                                class="card-action"
                                v-for="(percent, betKey) in handStrategy[item]
                                    .bet"
                                :key="betKey"
                            >
                                <span>{{ getLabel(betKey) }}</span>
                                <span>{{ percent }}</span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="strategy-right">
                <el-switch
                    v-model="ruleFlag"
                    active-text="满足所有条件"
                    inactive-text="满足任意条件"
                >
                </el-switch>
                <el-table
                    class="hand-make-table"
                    :data="makeStrategy"
                    @selection-change="handleMakeSelectChange"
                    :height="'420px'"
                    :header-cell-style="{ 'text-align': 'left' }"
                >
                    <el-table-column type="selection" width="45">
                    </el-table-column>
                    <el-table-column
                        v-for="(item, index) of tableColumn"
                        :key="item.prop"
                        :prop="item.prop"
                        :label="getLabel(item.label)"
                        :width="getTableColumnWidth(index, item.prop)"
                        sortable
                    ></el-table-column>
                </el-table>
                <el-table
                    class="hand-draw-table"
                    :data="drawStrategy"
                    @selection-change="handleDrawSelectChange"
                    :height="'300px'"
                    :header-cell-style="{ 'text-align': 'left' }"
                >
                    <el-table-column type="selection" width="45">
                    </el-table-column>
                    <el-table-column
                        v-for="(item, index) of tableColumn"
                        :key="item.prop"
                        :prop="item.prop"
                        :label="getLabel(item.label)"
                        :width="getTableColumnWidth(index, item.prop)"
                        sortable
                    ></el-table-column>
                </el-table>
            </div>
        </div>
    </el-dialog>
</template>

<script>
import BetRender from "./bet-render";
import {
    getSuitArray,
    suitToEmoji,
    getBetDesc,
    makeOrder,
    drawOrder,
    accumulateBetAndCombo,
    getDrawDesc,
    getMakeDesc,
    flopBoardHtml,
} from "@/utils/poker/poker-config";
import BetSummary from "@/components/bet-summary";
export default {
    name: "HandStrategy",
    components: {
        BetRender,
        BetSummary,
    },
    props: {
        handStrategy: {
            type: Object,
            default: () => {
                return {};
            },
        },
        board: {
            type: String,
        },
        isOpen: {
            type: Boolean,
        },
    },
    data() {
        return {
            cardRange: [14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
            cardMap: {
                14: "A",
                13: "K",
                12: "Q",
                11: "J",
                10: "T",
                9: 9,
                8: 8,
                7: 7,
                6: 6,
                5: 5,
                4: 4,
                3: 3,
                2: 2,
            },
            currentSelectHand: "",
            selectedMake: [],
            selectedDraw: [],
            ruleFlag: true,
        };
    },
    computed: {
        cellStrategy() {
            let strategy = {};
            for (let index of this.cardRange) {
                for (let index2 of this.cardRange) {
                    let cellDesc = this.getCellDesc(index, index2);
                    let cellPercent = this.getCellPercent(cellDesc);
                    strategy[cellDesc] = cellPercent;
                }
            }
            return strategy;
        },
        isOpenDialog: {
            get() {
                return this.isOpen;
            },
            set() {
                this.closeDialog();
            },
        },
        currentHands() {
            let handArray = [];
            let suitArray = getSuitArray(this.currentSelectHand);
            for (let suit of suitArray) {
                handArray.push(
                    `${this.currentSelectHand[0]}${suit[0]}${this.currentSelectHand[1]}${suit[1]}`
                );
            }
            return handArray;
        },
        handClass() {
            if (this.currentSelectHand[0] === this.currentSelectHand[1]) {
                return "hand_w3_h2";
            } else if (this.currentSelectHand[2] === "o") {
                return "hand_w3_h4";
            }
            return "hand_w2_h2";
        },
        tableColumn() {
            let tableColumn = [
                {
                    label: "手牌特征",
                    prop: "hand_desc",
                },
                {
                    label: "组合数",
                    prop: "combos",
                },
            ];
            if (this.makeStrategy.length > 0) {
                for (let betKey in this.makeStrategy[0].bet) {
                    tableColumn.push({
                        label: betKey,
                        prop: `bet.${betKey}`,
                    });
                }
            }
            return tableColumn;
        },
        makeStrategy() {
            let strategy = {};
            let strategyArray = [];
            for (let hand in this.handStrategy) {
                accumulateBetAndCombo(
                    "make",
                    strategy,
                    this.handStrategy[hand]
                );
            }
            for (let makeKey in strategy) {
                let bet = strategy[makeKey].bet;
                for (let betKey in bet) {
                    bet[betKey] = parseFloat(
                        (bet[betKey] / strategy[makeKey].combos).toFixed(2)
                    );
                }
                strategyArray.push({
                    hand_spec: makeKey,
                    hand_desc: getMakeDesc(makeKey),
                    bet,
                    combos: parseFloat(strategy[makeKey].combos.toFixed(2)),
                });
            }
            strategyArray.sort((a, b) => {
                return (
                    makeOrder.indexOf(a.hand_spec) -
                    makeOrder.indexOf(b.hand_spec)
                );
            });
            return strategyArray;
        },
        drawStrategy() {
            let strategy = {};
            let strategyArray = [];
            for (let hand in this.handStrategy) {
                accumulateBetAndCombo(
                    "draw",
                    strategy,
                    this.handStrategy[hand]
                );
            }
            for (let drawKey in strategy) {
                let bet = strategy[drawKey].bet;
                for (let betKey in bet) {
                    bet[betKey] = parseFloat(
                        (bet[betKey] / strategy[drawKey].combos).toFixed(2)
                    );
                }
                strategyArray.push({
                    hand_spec: drawKey,
                    hand_desc: getDrawDesc(drawKey),
                    bet,
                    combos: parseFloat(strategy[drawKey].combos.toFixed(2)),
                });
            }
            strategyArray.sort((a, b) => {
                return (
                    drawOrder.indexOf(a.hand_spec) -
                    drawOrder.indexOf(b.hand_spec)
                );
            });
            return strategyArray;
        },
        betSummary() {
            let betSummary = {};
            for (let hand in this.handStrategy) {
                this.accumulateBetSummary(betSummary, this.handStrategy[hand]);
            }
            for (let betKey in betSummary) {
                betSummary[betKey].percent = parseFloat(
                    (
                        betSummary[betKey].percent /
                        betSummary[betKey].totalCombos
                    ).toFixed(2)
                );
                betSummary[betKey].combos = parseFloat(
                    betSummary[betKey].combos.toFixed(2)
                );
            }
            return betSummary;
        },
    },
    watch: {
        handStrategy(val) {
            for (let item in val) {
                if (item[0] === item[2]) {
                    this.currentSelectHand = `${item[0]}${item[2]}`;
                } else {
                    if (item[1] === item[3]) {
                        this.currentSelectHand = `${item[0]}${item[2]}s`;
                    } else {
                        this.currentSelectHand = `${item[0]}${item[2]}o`;
                    }
                }
                break;
            }
        },
    },
    methods: {
        getFlopBoardHtml(flopBoard) {
            return flopBoardHtml(flopBoard);
        },

        getCellDesc(index, index2) {
            if (index > index2) {
                return `${this.cardMap[index]}${this.cardMap[index2]}s`;
            } else if (index === index2) {
                return `${this.cardMap[index]}${this.cardMap[index2]}`;
            } else {
                return `${this.cardMap[index2]}${this.cardMap[index]}o`;
            }
        },
        getCellPercent(hand) {
            let bet = null;
            let suitArray = getSuitArray(hand);
            let count = 0;
            let ret = {};
            for (let item of suitArray) {
                let handItem = `${hand[0]}${item[0]}${hand[1]}${item[1]}`;
                if (this.handStrategy[handItem]) {
                    if (
                        !this.checkHandFilterFlag(this.handStrategy[handItem])
                    ) {
                        continue;
                    }
                    if (bet == null) {
                        bet = {
                            ...this.handStrategy[handItem].bet,
                        };
                    } else {
                        for (let key in bet) {
                            bet[key] += this.handStrategy[handItem].bet[key];
                        }
                    }
                    count++;
                }
            }
            if (count >= 0) {
                for (let key in bet) {
                    ret[key] = bet[key] / count;
                }
            }

            return ret;
        },
        getRangeHeight(index, index2) {
            let desc = this.getCellDesc(index, index2);
            let suitArray = getSuitArray(desc);
            let combos = 0;
            let count = 0;
            for (let item of suitArray) {
                let handItem = `${desc[0]}${item[0]}${desc[1]}${item[1]}`;
                if (!this.handStrategy[handItem]) {
                    continue;
                }
                if (!this.checkHandFilterFlag(this.handStrategy[handItem])) {
                    continue;
                }
                combos += this.handStrategy[handItem].combos;
                count++;
            }
            if (count == 0) {
                return `0`;
            } else {
                return `${(combos * 100) / count}%`;
            }
        },
        closeDialog() {
            this.$emit("update:isOpen", false);
        },
        getHandHtml(hand) {
            return (
                `<span style="color:${suitToEmoji[hand[1]].color}">${hand[0]}${
                    suitToEmoji[hand[1]].emoji
                }</span>` +
                `<span style="color:${suitToEmoji[hand[3]].color}">${hand[2]}${
                    suitToEmoji[hand[3]].emoji
                }</span>`
            );
        },
        handleCardChange(index, index2) {
            let desc = this.getCellDesc(index, index2);
            this.currentSelectHand = desc;
        },
        getTableColumnWidth(index, prop) {
            switch (prop) {
                case "hand_desc":
                    return "110px";
                case "combos":
                    return "90px";
                case "bet.r_a":
                case "bet.r_m":
                case "bet.r_s":
                case "bet.f":
                    return "90px";
                case "bet.r_b":
                    return "100px";
                case "bet.cl":
                    return "88px";
                case "bet.f":
                    return "78px";
            }
            return null;
        },
        getLabel(label) {
            let desc = getBetDesc(label);
            return desc ? desc : label;
        },
        handleMakeSelectChange(val) {
            this.selectedMake = val.map((item) => {
                return item.hand_spec;
            });
        },

        handleDrawSelectChange(val) {
            this.selectedDraw = val.map((item) => {
                return item.hand_spec;
            });
        },

        checkHandFilterFlag(strategyBoardHand) {
            let flag = false;
            if (
                this.selectedMake.length == 0 &&
                this.selectedDraw.length == 0
            ) {
                flag = true;
            } else {
                if (this.ruleFlag) {
                    let checkMakeSucc = false;
                    if (this.selectedMake.length > 0) {
                        if (!strategyBoardHand.desc.make) {
                            if (
                                !(
                                    this.selectedMake.length === 1 &&
                                    this.selectedMake[0] == "no_make"
                                )
                            ) {
                                return;
                            } else {
                                checkMakeSucc = true;
                            }
                        }
                        if (!checkMakeSucc) {
                            for (let handSpec of this.selectedMake) {
                                if (!strategyBoardHand.desc.make[handSpec]) {
                                    return;
                                }
                            }
                        }
                    }
                    if (this.selectedDraw.length > 0) {
                        if (!strategyBoardHand.desc.draw) {
                            if (
                                !(
                                    this.selectedDraw.length === 1 &&
                                    this.selectedDraw[0] == "no_draw"
                                )
                            ) {
                                return;
                            } else {
                                flag = true;
                            }
                        }
                        if (!flag) {
                            for (let handSpec of this.selectedDraw) {
                                if (!strategyBoardHand.desc.draw[handSpec]) {
                                    return;
                                }
                            }
                        }
                    }
                    flag = true;
                } else {
                    do {
                        if (this.selectedMake.length > 0) {
                            if (
                                !strategyBoardHand.desc.make &&
                                this.selectedMake.indexOf("no_make") !== -1
                            ) {
                                flag = true;
                                break;
                            }
                            if (strategyBoardHand.desc.make) {
                                for (let handSpec of this.selectedMake) {
                                    if (strategyBoardHand.desc.make[handSpec]) {
                                        flag = true;
                                        break;
                                    }
                                }
                                if (flag) {
                                    break;
                                }
                            }
                        }
                        if (this.selectedDraw.length > 0) {
                            if (
                                !strategyBoardHand.desc.draw &&
                                this.selectedDraw.indexOf("no_draw") !== -1
                            ) {
                                flag = true;
                                break;
                            }
                            if (strategyBoardHand.desc.draw) {
                                for (let handSpec of this.selectedDraw) {
                                    if (strategyBoardHand.desc.draw[handSpec]) {
                                        flag = true;
                                        break;
                                    }
                                }
                            }
                        }
                    } while (0);
                }
            }
            return flag;
        },

        accumulateBetSummary(betSummary, strategyBoardHand) {
            let flag = this.checkHandFilterFlag(strategyBoardHand);

            if (!flag) {
                return;
            }
            if (Object.keys(betSummary) == 0) {
                for (let betKey in strategyBoardHand.bet) {
                    betSummary[betKey] = {
                        percent:
                            strategyBoardHand.bet[betKey] *
                            strategyBoardHand.combos,
                        combos:
                            (strategyBoardHand.combos *
                                strategyBoardHand.bet[betKey]) /
                            100,
                        totalCombos: strategyBoardHand.combos,
                    };
                }
            } else {
                for (let betKey in strategyBoardHand.bet) {
                    betSummary[betKey].percent =
                        betSummary[betKey].percent +
                        strategyBoardHand.bet[betKey] *
                            strategyBoardHand.combos;
                    betSummary[betKey].totalCombos =
                        betSummary[betKey].totalCombos +
                        strategyBoardHand.combos;
                    betSummary[betKey].combos =
                        betSummary[betKey].combos +
                        (strategyBoardHand.combos *
                            strategyBoardHand.bet[betKey]) /
                            100;
                }
            }
        },
    },
};
</script>

<style lang="scss">
.hand-strategy {
    width: 100%;
    height: 100%;
    display: flex;

    .hand-table {
        display: flex;
        flex-direction: column;
        margin-right: 5px;
        .hand-table-row {
            display: flex;

            .hand-table-cell {
                width: 47px;
                height: 55.8px;
                border: 1px solid black;
                margin: 0px -1px -1px 0px;
                background: grey;
                position: relative;

                .hand-desc {
                    position: absolute;
                    top: 0px;
                    left: 4px;
                    width: 100%;
                    height: 100%;
                    color: #000;
                }
            }
        }
    }

    .strategy-middle {
        min-height: 100%;
        width: 400px;

        display: flex;
        flex-direction: column;
        margin-right: 5px;

        .bet-summary {
            height: 240px;
            width: 100%;
        }

        .bet-detail {
            flex: 1;
            line-height: 0;

            .bet-detail-item {
                display: inline-block;
                position: relative;
                background: grey;
                border: 1px solid black;
                margin: 0px -1px -1px 0px;
                height: 14px;
                box-sizing: border-box;

                .detail-item-title {
                    background: #fff;
                    border-bottom-right-radius: 4px;
                    top: 0;
                    left: 0;
                    position: absolute;
                    display: flex;
                    z-index: 1000;
                    span {
                        line-height: 14px;
                    }
                }

                .detail-item-content {
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100%;
                }

                .detail-item-graph {
                    bottom: 0;
                    left: 0;
                    width: 100%;
                    display: flex;
                    flex-direction: column;
                    position: absolute;

                    .card-action {
                        display: flex;
                        justify-content: space-between;
                        height: 16px;
                        color: #000;
                        padding-left: 5px;
                        padding-right: 5px;
                        font-size: 16px;
                    }
                }
            }
        }

        .hand_w3_h2 {
            .bet-detail-item {
                width: 33%;
                height: 50%;
            }
        }

        .hand_w3_h4 {
            .bet-detail-item {
                width: 33%;
                height: 25%;
            }
        }

        .hand_w2_h2 {
            .bet-detail-item {
                width: 50%;
                height: 50%;
            }
        }
    }

    .strategy-right {
        flex: 1;

        .el-table__row {
            height: 40px;
        }
    }
}
</style>
